package com.hb.G_协程.A_协程基础

import kotlinx.coroutines.*


/**
 * 结果是相似的，但是这些代码只使用了非阻塞的函数 delay。
 * 调用了 runBlocking 的主线程会一直 阻塞 直到 runBlocking 内部的协程执行完毕。
 */
fun main() {
    /**
     * CoroutineScope:
     * 定义新协程的范围。 每个协程生成器都是 CoroutineScope 的扩展，并继承其coroutineContext以自动传播上下文元素和取消。
     * 获取范围的独立实例的最佳方法是CoroutineScope（）和MainScope（）工厂函数。 可以使用plus运算符将其他上下文元素附加到范围。
     * 不建议手动实现此接口，而是应首选通过委托实现。 按照约定，作用域的上下文应包含一个作业实例以强制执行结构化并发。
     * 每个协程构建器（如launch ， async等）和每个作用域函数（如coroutineScope ， withContext等）在其运行的内部代码块中提供其自己的范围以及其Job实例。 按照惯例，它们都在完成自身之前等待块中的所有协程完成，从而加强了结构化并发的纪律。
     * 应该在具有明确定义的生命周期并负责启动子协程的实体上实现（或用作字段） CoroutineScope 。 在Android上，此类实体的示例是Activity。 该接口的用法如下所示：
            class MyActivity : AppCompatActivity(), CoroutineScope by MainScope() {
            override fun onDestroy() {
            cancel() // cancel is extension on CoroutineScope
            }

     launch
    在不阻塞当前线程的情况下启动新的协程，并将对协程的引用作为Job返回。 当取消结果作业时，协程被取消。
    协程上下文是从CoroutineScope继承的。 可以使用context参数指定其他上下文元素。 如果上下文没有任何调度程序或任何其他ContinuationInterceptor ，则使用Dispatchers.Default 。 父作业也继承自CoroutineScope ，但也可以用相应的coroutineContext元素覆盖。
    默认情况下，协程将立即安排执行。 其他启动选项可以通过start参数指定。 有关详细信息，请参见CoroutineStart 。 可以将可选的启动参数设置为CoroutineStart.LAZY以延迟启动协程。 在这种情况下，协程作业将以新状态创建。 可以使用start函数显式启动它，并且在join的第一次调用时将隐式启动它。
    默认情况下，此协程中未捕获的异常会取消上下文中的父作业（除非明确指定了CoroutineExceptionHandler ），这意味着当将launch与另一个协程的上下文一起使用时，任何未捕获的异常都会导致父协程的取消。



    CoroutineStart:枚举类
    为协程构建器定义启动选项。 它在launch ， async和其他协程生成器功能的start参数中使用。
    协程启动选项的摘要是：
    默认-立即根据协程安排执行协程;
    LAZY-仅在需要时才懒惰地启动协程；
    ATOMIC-原子地（以不可取消的方式）根据协程的上下文来调度协程以执行该协程；
    UNDISPATCHED-立即执行协程，直到其在当前线程中的第一个挂起点

     */
    GlobalScope.launch { // 在后台启动一个新的协程并继续
        //launch函数，接收的最后一个参数是函数
        delay(1000L)
        println("kotlin coroutines!")
    }
    println("Hello,") // 主线程中的代码会立即执行
    val a=runBlocking {     // 但是这个表达式阻塞了主线程
        //阻塞主线程的执行
        delay(2000L)  // ……我们延迟 2 秒来保证 JVM 的存活

    }
    println("world")
}